package com.multimedia.scala.euler

import scala.collection.mutable.ListBuffer
import scala.annotation.tailrec
import scala.concurrent.MailBox
import scala.actors.Actor._
import scala.actors.Actor

object Asd66 {
    def main(args : Array[String]) : Unit = {
    	val box = new MailBox()
    	val max = 1000
    	val a = (2 to Math.sqrt(max).toInt).map(x=>x*x).toSet
    	(2 to max).filterNot(a(_)).foreach(x=>{
    	    //println(x)
    	    box send Count(x)
    	})
    	
    	val slaves = (1 to 4).map(x=>new Slave(box))
    	slaves.foreach(_.start())
    	var rez = new ListBuffer[Tuple2[Long, Long]]()
    	var maxD = 0.0
    	var maxX = 0.0
    	var maxY = 0.0
    	(2 to max).filterNot(a(_)).foreach(y=>{
    	    box receive {
    	      case Result(x, y, d) => {
    	          rez+=d->x
    	          println(x, y, d)
    	          if (maxX<x) {
    	              maxX = x
    	              maxD = d
    	              maxY = y
    	          } else if (maxX==x&&maxD>d) {
    	              maxX = x
    	              maxD = d
    	              maxY = y
    	          }
    	      }
    	    }
    	})
    	(1 to 4).foreach(x=>box send Stop)
    	println("x="+maxX+" y="+maxY+" d="+maxD)
    }


    class Slave(box: MailBox) extends Actor {
        def solve(d: Double): (Double, Double) = {
            @tailrec
            def findRez(d: Double, x: Double): (Double, Double) = {
	            def y = Math.sqrt((x*x-1)/d)
	
	            val rez = y
	            if (rez-Math.ceil(rez)==0) return (x, rez)
	            else findRez(d, x + 1)
            }
            
            findRez(d, Math.sqrt(d).floor)
        }
        def act() {
            loop {
                box receive {
                  case Count(d) => {
                    val rez = solve(d)
                    box send Result(rez._1.toLong, rez._2.toLong, d)
                  }
                  case Stop => exit()
                }
            }
        }
    }

    case class Stop
    case class Count(d: Int)
    case class Result(x: Long, y: Long, d: Long)
}
